/*
 *  SoundListTester.cpp
 *  SoundController0002
 *
 *  Created by jiro on 11/06/12.
 *  Copyright 2011 jiro music. All rights reserved.
 *
 */

#include "SoundListTester.h"

#include "../SoundList.h"
#include "../../../sc/Tester/CustomAssert.h"
#include "../../../sc/Common/WellTemperament.h"
#include "../../../sc/AllExceptions.h"

namespace sc
{
namespace hs
{

	void SoundListTester::TestAll()
	{
//		try 
//		{
		
			Test_GetAllHowls000();
			Test_GetAllHowls001();
			Test_GetAllHowls002();

//			Test_FindNotesIncludeHarmonics000();
//
//			Test_FindNotesIncludeHarmonics001();
//
//			Test_IsExistNotesIncludeHarmonics000();
//
//			Test_IsExistNotesIncludeHarmonics001();

//			Test_IsExistHowlOfFrequency000();
//
//			Test_FindHowlOfFrequency000();
//
//			Test_GetAllHarmonicsList000();

			Test_GetNearbyWellTemperamentNotes000();
			Test_GetNearbyWellTemperamentNotes001();
			Test_GetNearbyWellTemperamentNotes002();

			Test_FindNoteWhereMidiNumber000();
			Test_FindNoteWhereMidiNumber001();
			Test_FindNoteWhereMidiNumber002();
			Test_FindNoteWhereMidiNumber003();
//		}
//		catch( NotImplementedException& exception )
//		{
//			cout << exception.what() << endl;
//		}
	}

	void SoundListTester::Test_GetAllHowls000()
	{
		SoundList chord;
		chord.push_back( Sound( Sound::SingleSineWave, Note::A4 ) );
		chord.push_back( Sound( Sound::SingleSineWave, Note::E5 ) );

		const HowlSet& howlList = chord.GetHowlSet();

//		cout << howlList.ToString() << endl;
		AssertEqual( howlList.size(), 15 ); 
		AssertTrue( howlList.IsExistHowlFrequency( 1.48977 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 2.97954 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 4.46932 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 5.95909 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 7.44886 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 8.93863 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 10.4284 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 11.9181787 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 13.40795113668355 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 14.897723485202732 ) );

	}

	void SoundListTester::Test_GetAllHowls001()
	{
		SoundList chord;
		chord.push_back( Sound( Sound::SingleSineWave, Note::A0 ) );
		chord.push_back( Sound( Sound::SingleSineWave, Note::ASharp0 ) );

		const HowlSet& howlList = chord.GetHowlSet();
		AssertEqual( howlList.size(), 1993 );
		AssertTrue( howlList.IsExistHowlFrequency( 1.63524 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 3.27047 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 4.90571 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 6.54094 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 8.17618 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 9.81141 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 11.44664566 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 13.08188076 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 14.41811924 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 14.71711585 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 12.78288415 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 11.147649 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 9.51241 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 7.87718 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 6.24194 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 4.60671 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 2.97147 ) );
	}

	void SoundListTester::Test_GetAllHowls002()
	{
	
		SoundList chord;
		chord.push_back( Sound( Sound::SingleSineWave, Note::A3 ) );
		chord.push_back( Sound( Sound::SingleSineWave, Note::B3 ) );
		chord.push_back( Sound( Sound::SingleSineWave, Note::E4 ) );

		const HowlSet& howlList = chord.GetHowlSet();
		AssertEqual( howlList.size(), 76 );
		AssertTrue( howlList.IsExistHowlFrequency( 4.466794976 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 0.7448861743 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 1.489772349 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 2.234658523 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 2.979544697 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 3.724430871 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 1.116068226 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 2.232136453 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 3.348204679 ) );
		AssertTrue( howlList.IsExistHowlFrequency( 4.464272905 ) );

	}

	void SoundListTester::Test_FindNotesIncludeHarmonics000()
	{
		throw NotImplementedException( "void SoundListTester::Test_FindNotesIncludeHarmonics000()" );
	/*
		SoundList noteList;
		::sc::Note::MidiNumber numbers[] = { sc::Note::A4, sc::Note::B4, sc::Note::C4 };
		double freqs[] = { WellTemperament::GetFrequency( numbers[ 0 ] ), WellTemperament::GetFrequency( numbers[ 1 ] ), WellTemperament::GetFrequency( numbers[ 2 ] ) };

		for ( int i = 0; i < sizeof( freqs ) / sizeof( double ); i++ )
		{
			Sound note( Sound::SingleSineWave, numbers[ i ] );
			noteList.push_back( note );
		}

		SoundList noteListOut;

		noteList.FindNotesIncludeHarmonics( freqs[ 0 ], noteListOut );
		AssertEqual( noteListOut.size(), 1 );
		AssertEqual( noteListOut[ 0 ].GetFrequency(), freqs[ 0 ] );
		noteListOut.clear();

		noteList.FindNotesIncludeHarmonics( 2 * freqs[ 1 ], noteListOut );
		AssertEqual( noteListOut.size(), 1 );
		AssertEqual( noteListOut[ 0 ].GetFrequency(), freqs[ 1 ] );
		noteListOut.clear();
*/
	}

	void SoundListTester::Test_FindNotesIncludeHarmonics001()
	{
		throw NotImplementedException( "void SoundListTester::Test_FindNotesIncludeHarmonics001()" );
/*		
		SoundList noteList;
		::sc::Note::MidiNumber numbers[] = { sc::Note::A4, sc::Note::B4, sc::Note::C4 };
		double freqs[] = { WellTemperament::GetFrequency( numbers[ 0 ] ), WellTemperament::GetFrequency( numbers[ 1 ] ), WellTemperament::GetFrequency( numbers[ 2 ] ) };

		for ( int i = 0; i < sizeof( freqs ) / sizeof( double ); i++ )
		{
			Sound note( Sound::SingleSineWave, numbers[ i ] );
			noteList.push_back( note );
		}

		SoundList noteListOut;

		noteList.FindNotesIncludeHarmonics( freqs[ 0 ], freqs[ 0 ] + 1, noteListOut );
		AssertEqual( noteListOut.size(), 2 );
		AssertEqual( noteListOut[ 0 ].GetFrequency(), freqs[ 0 ] );
		noteListOut.clear();

		noteList.FindNotesIncludeHarmonics( freqs[ 0 ] + 1, freqs[ 0 ] + 1.1, noteListOut );
		AssertEqual( noteListOut.size(), 0 );
		noteListOut.clear();
		*/
	}

	void SoundListTester::Test_IsExistNotesIncludeHarmonics000()
	{
		throw NotImplementedException( "void SoundListTester::Test_IsExistNotesIncludeHarmonics000()" );
	/*
		SoundList noteList;
		double freqs[] = { 100, 101, 200 };

		for ( int i = 0; i < sizeof( freqs ) / sizeof( double ); i++ )
		{
			Sound note( Sound::SingleSineWave, freqs[ i ] );
			noteList.push_back( note );
		}

		SoundList noteListOut;
		AssertEqual( noteList.IsExistNotesIncludeHarmonics( 100 ), true );
		AssertEqual( noteList.IsExistNotesIncludeHarmonics( 100 + 0.001 ), false );
		AssertEqual( noteList.IsExistNotesIncludeHarmonics( 200 ), true );
		AssertEqual( noteList.IsExistNotesIncludeHarmonics( 101 ), true );
		AssertEqual( noteList.IsExistNotesIncludeHarmonics( 202 ), true );
		*/
	}

	void SoundListTester::Test_IsExistNotesIncludeHarmonics001()
	{
		throw NotImplementedException( "void SoundListTester::Test_IsExistNotesIncludeHarmonics001()" );
	/*
		SoundList noteList;
		double freqs[] = { 100, 101, 200 };

		for ( int i = 0; i < sizeof( freqs ) / sizeof( double ); i++ )
		{
			Sound note( Sound::SingleSineWave, freqs[ i ] );
			noteList.push_back( note );
		}

		SoundList noteListOut;

		AssertEqual( noteList.IsExistNotesIncludeHarmonics( 100, 101 ), true );
		AssertEqual( noteList.IsExistNotesIncludeHarmonics( 100 + 0.0001, 101 - 0.0001 ), false );
		AssertEqual( noteList.IsExistNotesIncludeHarmonics( 200, 202 ), true );
		AssertEqual( noteList.IsExistNotesIncludeHarmonics( 201, 202 ), true );
		*/
	}

	void SoundListTester::Test_IsExistHowlOfFrequency000()
	{
		throw NotImplementedException( "void SoundListTester::Test_IsExistHowlOfFrequency000()" );
	/*
		SoundList chord;
		chord.push_back( Sound( Sound::SingleSineWave, 100 ) );
		chord.push_back( Sound( Sound::SingleSineWave, 101 ) );
		chord.push_back( Sound( Sound::SingleSineWave, 200 ) );

		AssertEqual( chord.IsExistHowlFrequency( 1 ), true );
		AssertEqual( chord.IsExistHowlFrequency( 2 ), true );
		AssertEqual( chord.IsExistHowlFrequency( 3 ), true );
		AssertEqual( chord.IsExistHowlFrequency( 4 ), true );
		AssertEqual( chord.IsExistHowlFrequency( 100 ), true );
		AssertEqual( chord.IsExistHowlFrequency( 99 ), true );

		AssertEqual( chord.IsExistHowlFrequency( 3.5 ), false );
		AssertEqual( chord.IsExistHowlFrequency( - 5 ), false );
		AssertEqual( chord.IsExistHowlFrequency( 98 ), false );
		AssertEqual( chord.IsExistHowlFrequency( 101 ), false );
		*/
		
	}

	void SoundListTester::Test_FindHowlOfFrequency000()
	{
		throw NotImplementedException( "void SoundListTester::Test_FindHowlOfFrequency000()" );
	}

	void SoundListTester::Test_GetAllHarmonicsList000()
	{
		throw NotImplementedException( "void SoundListTester::Test_GetAllHarmonicsList000()" );
	}

	void SoundListTester::Test_GetNearbyWellTemperamentNotes000()
	{
		Sound sound0( Sound::SingleSineWave, sc::Note::A4 );
		Sound sound1( Sound::SingleSineWave, sc::Note::E4 );
		SoundList chord;
		chord.push_back( sound0 );
		chord.push_back( sound1 );
		const Sound::NearbyWellTemperamentNotes& nearbyNotes = chord.GetNearbyWellTemperamentNotes();

//		cout << nearbyNotes.size() << "\n" << Sound::ToString( nearbyNotes ) << endl;

		AssertEqual( nearbyNotes.size(), 48 );
		
		Sound::NearbyWellTemperamentNotes::const_iterator iter;

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::A4, 3 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::E6 );

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::A4, 6 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::E7 );

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::A4, 9 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::B7 );

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::A4, 12 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::E8 );

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::A4, 19 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::C9 );

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::A4, 24 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::E9 );

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::E4, 3 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::B5 );

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::E4, 5 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::GSharp6 );

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::E4, 6 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::B6 );

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::E4, 9 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::FSharp7 );

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::E4, 12 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::B7 );

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::E4, 18 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::FSharp8 );

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::E4, 19 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::G8 );

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::E4, 24 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::B8 );

		iter = nearbyNotes.find( HarmonicSound( Sound::SingleSineWave, sc::Note::E4, 57 ) );
		AssertTrue( iter != nearbyNotes.end() );
		AssertEqual( iter->second, sc::Note::D10 );

	}
	

	void SoundListTester::Test_GetNearbyWellTemperamentNotes001()
	{
//		AssertTrue( false );
	}

	void SoundListTester::Test_GetNearbyWellTemperamentNotes002()
	{
//		AssertTrue( false );
	}
	
	void SoundListTester::Test_FindNoteWhereMidiNumber000()
	{
		SoundList list;
		std::vector< HarmonicSound > harmonicSounds;
		list.push_back( Sound( Sound::SingleSineWave, ::sc::Note::D1 ) );
		bool result = list.FindNoteWhereMidiNumber( ::sc::Note::B2, harmonicSounds );
		AssertTrue( result );
		AssertEqual( harmonicSounds.size(), 2 );

		AssertEqual( harmonicSounds[ 0 ].GetNthOfHarmonic(), 3 );
		AssertEqual( harmonicSounds[ 1 ].GetNthOfHarmonic(), 4 );
	}
	
	void SoundListTester::Test_FindNoteWhereMidiNumber001()
	{
		SoundList list;
		std::vector< HarmonicSound > harmonicSounds;
		list.push_back( Sound( Sound::SingleSineWave, ::sc::Note::D1 ) );
		bool result = list.FindNoteWhereMidiNumber( ::sc::Note::D3, harmonicSounds );
		AssertTrue( result );
		AssertEqual( harmonicSounds.size(), 3 );

		AssertEqual( harmonicSounds[ 0 ].GetNthOfHarmonic(), 3 );
		AssertEqual( harmonicSounds[ 1 ].GetNthOfHarmonic(), 4 );
		AssertEqual( harmonicSounds[ 2 ].GetNthOfHarmonic(), 5 );
		
		for ( int i = 0; i < harmonicSounds.size(); i++ )
		{
//			cout << harmonicSounds[ i ].ToString() << endl;
		}
	}

	void SoundListTester::Test_FindNoteWhereMidiNumber002()
	{
//		AssertTrue( false );
	}

	void SoundListTester::Test_FindNoteWhereMidiNumber003()
	{
//		AssertTrue( false );
	}


}
}